/**
 * @file bsp_modem.c
 * @brief 
 * @author  ()
 * @version 1.0
 * @date 2024-09-13
 * 
 * @copyright Copyright (C) 2019 Queclink Wireless Solutions (ShenZhen) Co., Ltd. All Rights Reserved.
 * 
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version <th>Author  <th>Description
 * <tr><td>2024-09-13 <td>1.0     <td>     <td>内容
 * </table>
 */
#include "hal_adapter.h"
#include "bsp_modem.h"
#include "bsp_uart.h"
#include "cmsis_os2.h"

#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"

extern void Error_Handler(void);

int32_t bsp_modem_init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    
    /* enable the gpio clock */
    modem_gpioclk_enable();
    
    /* powerctrl pin */
    GPIO_InitStruct.Pin = MDM_PWR_CTRL_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(MDM_PWR_CTRL_PORT, &GPIO_InitStruct);

    // 默认下电状态
    bsp_modem_powerctrl_off();

    /* poweron pin */
    GPIO_InitStruct.Pin = MDM_PWR_ON_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(MDM_PWR_ON_PORT, &GPIO_InitStruct);

    /* DTR pin */
    GPIO_InitStruct.Pin = MDM_DTR_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(MDM_DTR_PORT, &GPIO_InitStruct);

    /* Ring pin */
    GPIO_InitStruct.Pin = MDM_RING_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(MDM_RING_PORT, &GPIO_InitStruct);

    /**USART2 GPIO Configuration
    PD6     ------> USART2_RX
    PD5     ------> USART2_TX
    */
    GPIO_InitStruct.Pin = MDM_UART_TX_PIN|MDM_UART_RX_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = MDM_UART_PORT_AF;
    HAL_GPIO_Init(MDM_UART_PORT, &GPIO_InitStruct);

    /* Peripheral clock enable */
    modem_uartclk_enable();
    
    bsp_uart_init(modem_uart_id);

    /* RST pin */
    GPIO_InitStruct.Pin = MDM_RST_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(MDM_RST_PORT, &GPIO_InitStruct);

    /* reset the lte module */
    HAL_GPIO_WritePin(MDM_RST_PORT, MDM_RST_PIN, GPIO_PIN_SET);
    osDelay(150);
    HAL_GPIO_WritePin(MDM_RST_PORT, MDM_RST_PIN, GPIO_PIN_RESET);
    
    return 0;
}


void bsp_modem_deinit(void)
{

}


/// @brief modem 上电/下电控制
void bsp_modem_powerctrl_on(void)
{
    HAL_GPIO_WritePin(MDM_PWR_CTRL_PORT, MDM_PWR_CTRL_PIN, GPIO_PIN_SET);
}

/// @brief modem 上电/下电控制
void bsp_modem_powerctrl_off(void)
{
    HAL_GPIO_WritePin(MDM_PWR_CTRL_PORT, MDM_PWR_CTRL_PIN, GPIO_PIN_RESET);
}


/// @brief modem 开机 拉低2s/关机 拉高2s
void bsp_modem_powerkey(int32_t status)
{
    if(status)
    {
        HAL_GPIO_WritePin(MDM_PWR_ON_PORT, MDM_PWR_ON_PIN, GPIO_PIN_RESET);
    }
    else 
    {
        HAL_GPIO_WritePin(MDM_PWR_ON_PORT, MDM_PWR_ON_PIN, GPIO_PIN_SET);
    }
    
}

/**
 * @brief modem上电状态
 * @return true 
 * @return false 
 */
bool bsp_modem_get_power_status(void)
{
    return (HAL_GPIO_ReadPin(MDM_PWR_CTRL_PORT, MDM_PWR_CTRL_PIN) == GPIO_PIN_SET);
   
}


/**
 * @brief 获取modem振铃状态
 * @return int32_t 
 */
int32_t bsp_modem_ring_get(void)
{
    return (HAL_GPIO_ReadPin(MDM_RING_PORT, MDM_RING_PIN) == GPIO_PIN_RESET);
}


#if 0
#define MDM_DTR_PIN			    	GPIO_PIN_9  /* 配置为推挽输出，1-空闲，0-MCU唤醒4G模块 */
#define MDM_DTR_PORT		    	GPIOB 
#endif
/**
 * @brief 设置modem数据传输标志
 * @param  status           My Param doc
 */
void bsp_modem_dtr_set(int32_t status)
{
    HAL_GPIO_WritePin(MDM_DTR_PORT, MDM_DTR_PIN, status ? GPIO_PIN_SET : GPIO_PIN_RESET);
}


bool bsp_modem_dtr_get(void)
{
    return ( HAL_GPIO_ReadPin(MDM_DTR_PORT, MDM_DTR_PIN) == GPIO_PIN_RESET);
}




#if 0
#define MDM_RING_PIN				GPIO_PIN_7  /* 配置为浮空输入，0-有效，1-空闲，4G模块唤醒MCU */
#define MDM_RING_PORT				GPIOB 
#endif
/**
 * @brief  打开 INT 中断
 * @note   固定使用"上升沿"触发中断.
 * @param  isr: [I], 中断服务程序, 请将该ISR注册到 INT1 中断服务程序中;
 *         ptr: [I], 中断服务程序 isr 使用的 ptr.
 * @retval none
 */
void bsp_modem_ri_int_enable(void (*isr)(void *ptr), void *ptr)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
	/* GPIO Ports Clock Enable */
	modem_gpioclk_enable();

	/*Configure GPIO pin : RI_Pin */
	GPIO_InitStruct.Pin = MDM_RING_PIN;
	GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	HAL_GPIO_Init(MDM_RING_PORT, &GPIO_InitStruct);

	/* EXTI interrupt init*/
	HAL_NVIC_SetPriority(EXTI7_IRQn, 0, 0);
	HAL_NVIC_EnableIRQ(EXTI7_IRQn);
}

/**
 * @brief  关闭 INT 中断
 */
void bsp_modem_ri_int_disable(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
	
    /* USER CODE BEGIN MX_GPIO_Init_1 */
	/* USER CODE END MX_GPIO_Init_1 */

	/* GPIO Ports Clock Enable */
	modem_gpioclk_enable();

	/*Configure GPIO pin : RI_Pin */
	GPIO_InitStruct.Pin = MDM_RING_PIN;
	GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	HAL_GPIO_Init(MDM_RING_PORT, &GPIO_InitStruct);

	/* EXTI interrupt init*/
	HAL_NVIC_SetPriority(EXTI7_IRQn, 0, 0);
	HAL_NVIC_DisableIRQ(EXTI7_IRQn);
}



/**
 * @brief modem串口写入数据 
 * @param  data             串口数据发送缓存地址
 * @param  size             串口数据长度
 * @return ssize_t 
 */
ssize_t bsp_modem_write(const void *data, size_t size)
{
    ssize_t wr_cnt = 0;
    
    wr_cnt = bsp_uart_itwrite(modem_uart_id, data, size);
    
    return wr_cnt;
}

/**
 * @brief 串口读取数据
 * @param  data             串口数据接收缓存地址
 * @param  size             最大读取长度
 * @return ssize_t 
 */
ssize_t bsp_modem_read(void *data, size_t size)
{
    ssize_t wr_cnt = 0;
    
    wr_cnt = bsp_uart_read(modem_uart_id, data, size);
    
    return wr_cnt;    
}

/**
 * @brief 设置串口波特率
 * @param  bps              目标串口波特率
 */
void bsp_modem_set_baudrate(uint32_t bps)
{
    bsp_uart_set_baudrate(modem_uart_id, bps);
    return;
}


/**
 * @brief 进入休眠
 * 
 * @return int32_t 
 */
int32_t modem_uart_sleep(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    HAL_GPIO_DeInit(MDM_UART_PORT, MDM_UART_TX_PIN|MDM_UART_RX_PIN|MDM_DTR_PIN);

    GPIO_InitStruct.Pin = MDM_UART_TX_PIN|MDM_UART_RX_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = MDM_UART_PORT_AF;
    HAL_GPIO_Init(MDM_UART_PORT, &GPIO_InitStruct);


    /* DTR pin */
    GPIO_InitStruct.Pin = MDM_DTR_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(MDM_DTR_PORT, &GPIO_InitStruct);

    // /* powerctrl pin */
    // GPIO_InitStruct.Pin = MDM_PWR_CTRL_PIN;
    // GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    // GPIO_InitStruct.Pull = GPIO_NOPULL;
    // GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    // HAL_GPIO_Init(MDM_PWR_CTRL_PORT, &GPIO_InitStruct);

    /* 设置RX中断(与Modem RI 管脚中断号冲突, 但可用) */
    bsp_modem_ri_int_enable(NULL, NULL); 

    return 0;
}

/**
 * @brief 使能串口唤醒
 * 
 */
void modem_uart_wakeup(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    /* 禁用中断 */
    bsp_modem_ri_int_disable();

    HAL_GPIO_DeInit(MDM_UART_PORT, MDM_UART_TX_PIN|MDM_UART_RX_PIN|MDM_DTR_PIN);

    GPIO_InitStruct.Pin = MDM_UART_TX_PIN|MDM_UART_RX_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = MDM_UART_PORT_AF;
    HAL_GPIO_Init(MDM_UART_PORT, &GPIO_InitStruct);

    /* DTR pin */
    GPIO_InitStruct.Pin = MDM_DTR_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(MDM_DTR_PORT, &GPIO_InitStruct);

    // /* powerctrl pin */
    // GPIO_InitStruct.Pin = MDM_PWR_CTRL_PIN;
    // GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    // GPIO_InitStruct.Pull = GPIO_NOPULL;
    // GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    // HAL_GPIO_Init(MDM_PWR_CTRL_PORT, &GPIO_InitStruct);

    
}


